package com.lucifer.treasure.enchant.effect;

import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents;
import net.fabricmc.fabric.api.event.player.AttackEntityCallback;
import net.minecraft.enchantment.EnchantmentEffectContext;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.EnchantmentLevelBasedValue;
import net.minecraft.enchantment.effect.EnchantmentEntityEffect;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.Vec3d;

public record LifeLeechEnchantmentEffect(EnchantmentLevelBasedValue healAmount) implements EnchantmentEntityEffect {
    public static final MapCodec<LifeLeechEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
            instance.group(
                    EnchantmentLevelBasedValue.CODEC.fieldOf("heal_amount").forGetter(LifeLeechEnchantmentEffect::healAmount)
            ).apply(instance, LifeLeechEnchantmentEffect::new)
    );

    public static void initialize() {
        // 监听攻击事件 - 每次攻击回复生命值
        AttackEntityCallback.EVENT.register((player, world, hand, entity, hitResult) -> {
            if (world.isClient() || !(player instanceof PlayerEntity)) {
                return ActionResult.PASS;
            }

            ItemStack weapon = player.getStackInHand(hand);
            if (weapon.isEmpty()) {
                return ActionResult.PASS;
            }

            // 检查武器是否有LifeLeech附魔
            var enchantments = EnchantmentHelper.getEnchantments(weapon);
            int level = 0;

            for (var entry : enchantments.getEnchantments()) {
                if (entry.getKey().isPresent()) {
                    String enchantmentId = entry.getKey().get().getValue().toString();
                    if (enchantmentId.equals("lucifer_treasure:life_leech")) {
                        level = Math.max(level, enchantments.getLevel(entry));
                    }
                }
            }

            if (level <= 0) {
                return ActionResult.PASS;
            }
            if (level > 0 && player.getHealth() < player.getMaxHealth()) {
                // 攻击时回复生命值（每级回复1点）
                player.heal(level);
            }

            return ActionResult.PASS;
        });

        // 监听死亡事件 - 击杀敌人时额外回复
        ServerLivingEntityEvents.AFTER_DEATH.register((entity, damageSource) -> {
            if (!(damageSource.getAttacker() instanceof PlayerEntity attacker)) {
                return;
            }

            // 检查主手和副手武器的Life Leech附魔等级
            int maxLevel = 0;
            maxLevel = Math.max(maxLevel, getLifeLeechLevel(attacker.getMainHandStack()));
            maxLevel = Math.max(maxLevel, getLifeLeechLevel(attacker.getOffHandStack()));

            if (maxLevel <= 0) {
                return;
            }
            
            if (maxLevel > 0 && attacker.getHealth() < attacker.getMaxHealth()) {
                // 计算击杀回复量：敌人最大生命值的1/5，最少4点
                int baseRestore = (int) Math.max(Math.ceil(entity.getMaxHealth() / 5.0f), 4);
                int minHeal = maxLevel; // 最小回复量等于附魔等级

                // 随机回复量在[minHeal, baseRestore + minHeal]范围内
                int healAmount = attacker.getWorld().getRandom().nextInt(baseRestore + 1) + minHeal;

                if (healAmount > 0) {
                    attacker.heal(healAmount);

                    // 生成心形粒子效果（可选）
                    if (attacker.getWorld() instanceof ServerWorld serverWorld) {
                        serverWorld.spawnParticles(
                                net.minecraft.particle.ParticleTypes.HEART,
                                attacker.getX(), attacker.getY() + 2.0, attacker.getZ(),
                                3, 0.5, 0.5, 0.5, 0.1
                        );
                    }
                }
            }
        });
    }

    /**
     * 从物品栈获取Life Leech附魔等级
     */
    private static int getLifeLeechLevel(ItemStack stack) {
        if (stack.isEmpty()) {
            return 0;
        }

        var enchantments = EnchantmentHelper.getEnchantments(stack);
        int maxLevel = 0;

        for (var entry : enchantments.getEnchantments()) {
            if (entry.getKey().isPresent()) {
                String enchantmentId = entry.getKey().get().getValue().toString();
                if (enchantmentId.equals("lucifer_treasure:life_leech")) {
                    maxLevel = Math.max(maxLevel, enchantments.getLevel(entry));
                }
            }
        }

        return maxLevel;
    }

    @Override
    public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) {
        // 主要逻辑在事件监听器中处理
        // 这个方法也可以用于post_attack事件触发的即时回复
        if (context.owner() instanceof PlayerEntity player && player.getHealth() < player.getMaxHealth()) {
            player.heal(level);
        }
    }

    @Override
    public MapCodec<? extends EnchantmentEntityEffect> getCodec() {
        return CODEC;
    }
} 